<!DOCTYPE html>
<html lang="zh">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="Content-Security-Policy"
        content="default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';">
    <title>设置</title>
</head>
<style>
    html,
    body {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
    }

    body::-webkit-scrollbar {
        width: 0;
        display: none;
    }

    * {
        box-sizing: border-box;
    }

    body {
        font-size: 12px;
        display: flex;
        flex-direction: column;
        margin: 0;
        padding: 10px;
        gap: 10px;
    }

    button {
        font-size: 12px;
    }

    input,
    select {
        min-width: 0;
    }

    .ml_config_bg {
        border: 1px solid #ccc;
        border-radius: 8px;
        margin-bottom: 10px;
        gap: 10px;
        margin: 0;
        display: flex;
        flex-direction: column;
    }

    #my_address_container {
        flex-grow: 1;
        display: flex;
        flex-direction: column;
        width: 100%;
    }

    .grid-label,
    .my_port,
    .my_address_item,
    #my_address_title {
        width: 100%;
        display: grid;
        /* 启用 Grid 布局 */
        grid-template-columns: auto 1fr;
        /* 第一列自适应，第二列占据剩余宽度 */
        align-items: center;
        /*子元素高度跟本身一样高*/
        white-space: nowrap;
        gap: 10px;
    }

    .my_port {
        grid-template-columns: 3fr 1fr;
    }

    #my_address_title {
        padding-left: 50px;
        grid-template-columns: 4fr 3fr 2fr;
    }

    .my_address_item {
        grid-template-columns: 50px 4fr 3fr 2fr;
        gap: 0;
    }

    .my_address_item input,
    .my_address_item select {
        height: 100%;
    }

    #my_tool {
        display: flex;
        justify-content: center;
        /* 水平居中 */
        gap: 10px;
        /* 按钮之间的间距 */
        margin-top: 10px;
        /* 可选，增加上方间距 */
    }

    #my_tool button {
        width: 60px;
    }

    #my_save_state_title {
        display: flex;
        align-items: center;
        /* 让子元素垂直居中 */
        gap: 5px;
        /* 控制文本与复选框的间距 */
    }
</style>

<body>
    <div id="my_config_1">
        <fieldset class="ml_config_bg">
            <legend>通信设置</legend>
            <div class="my_port">
                <label class="grid-label">
                    端口号
                    <select name="x" id="my_port">
                        <option value="0">None</option>
                    </select>
                </label>
                <button id="my_refresh">刷新</button>
            </div>
            <div class="my_baud">
                <label class="grid-label">
                    波特率
                    <select name="x" id="my_baud">
                        <option value="115200">115200</option>
                        <option value="9600">9600</option>
                    </select>
                </label>
            </div>
        </fieldset>
    </div>
    <div id="my_config_2">
        <fieldset class="ml_config_bg">
            <legend>采样频率设置</legend>
            <label for="my_fre" class="grid-label">采样频率
                <input type="number" class="ml_config_input" id="my_fre">
            </label>
        </fieldset>
    </div>
    <div id="my_config_3">
        <fieldset class="ml_config_bg">
            <legend>请选择地址(必填)</legend>
            <div id="my_address_title">
                <div>地址</div>
                <div>信号类型</div>
                <div>电平</div>
            </div>
            <div id="my_address_container">
                <template class="my_address_item_temp" id="my_address_item_temp">
                    <div class="my_address_item">
                        <label class="my_address_name">地址1</label>
                        <input type="text" class="my_address_input">
                        <select name="sign_type" class="my_sign_type" id="my_sign_type">
                        </select>
                        <select name="sign_type" class="my_flag" id="my_flag">
                        </select>
                    </div>
                </template>
            </div>
        </fieldset>
    </div>
    <div id="my_config_4">
        <fieldset class="ml_config_bg">
            <legend>保存数据至文件(可选)</legend>
            <label id="my_save_state_title" for="my_save_state">
                <input type="checkbox" id="my_save_state">
                是否将采集的数据保存至文件中
            </label>
            <label for="my_file_max" class="grid-label">每个文件最大点数
                <input type="number" class="my_file_max" id="my_file_max">
            </label>
            <button id="my_chooseFile">选择文件</button>
        </fieldset>
    </div>
    <div id="my_tool">
        <button id="my_config_enter">确定</button>
        <button id="my_config_cancel">取消</button>
    </div>
</body>
<script src="../js/util/extensions.js"></script>
<script>

    const my_port = document.getElementById('my_port');
    const my_baud = document.getElementById('my_baud');
    const refresh = document.getElementById('my_refresh');
    const frequency = document.getElementById('my_fre');
    const issave = document.getElementById('my_save_state');
    const fileMax = document.getElementById('my_file_max');
    const chooseFile = document.getElementById('my_chooseFile');
    const enterBtn = document.getElementById('my_config_enter');
    const cancelBtn = document.getElementById('my_config_cancel');

    let port = null;
    let cmd = 0x01;
    let address_list = [];
    const baud_key = 'my_baud';
    const frequency_key = 'my_frequency';

    document.addEventListener('DOMContentLoaded', async function () {
        ///选择端口号
        my_port.addEventListener('change', () => {
            // alert(`端口选择的是${my_port.value}`);
            //打开串口 
            MyAPI.log(`选择端口号: ${my_port.options[my_port.selectedIndex].text}`);
        });

        ///选择波特率
        my_baud.value = await electronStoreAPI.get(baud_key, '115200')
        my_baud.addEventListener('change', () => {
            MyAPI.log(`选择波特率: ${my_baud.value}`);
        });

        refresh.addEventListener('click', async () => {
            refreshPortList();
        });

        frequency.value = await electronStoreAPI.get(frequency_key, '100');
        frequency.addEventListener('change', () => {
            MyAPI.log(`频率采样数值 = ${frequency.value}`);
        })

        issave.addEventListener('change', () => {
            MyAPI.log(`采集的数据保存至文件${issave.checked}`);
        });

        fileMax.addEventListener('my_file_max', () => {
            MyAPI.log(`每个文件最大点数 = ${fileMax.value}`);
        });

        chooseFile.addEventListener('click', async () => {
            const path = await MyAPI.toBrowseFiles();
            if (path != null) {
                MyAPI.log(`当前浏览选中的文件是${path}`);
            }
        });

        enterBtn.addEventListener('click', async () => {
            if (my_port.value == '0') {
                alert('请选择端口号！');
            } else if (my_baud.value == '0') {
                alert('请选择波特率');
            } else {
                const input_list = document.querySelectorAll('.my_address_input');
                const map_list = Array.from(input_list).map((element, index) => ({ element, index }));
                const invalid_list = map_list.filter($0 => !$0.element.value.isHexStringBytes(4));
                const invalid_elements = invalid_list.map($0 => $0.element); // 获取不符合的元素
                const invalid_indexes = invalid_list.map($0 => $0.index); // 获取不符合的索引
                ///判断地址是不是有填错误
                if (invalid_elements.length > 0) {
                    alert(`地址${invalid_indexes[0] + 1}的${invalid_elements[0].value}格式错误`);
                } else {
                    updateLocal();
                    setTimeout(() => {
                        MyAPI.closePopupWindow();
                    }, 400);  // 200毫秒后执行
                }
            }
        });

        cancelBtn.addEventListener('click', () => {
            MyAPI.closePopupWindow();
        });
    });

    ///刷新端口列表
    async function refreshPortList() {
        try {
            const list = await serialAPI.listPorts(); // 调用主进程的 listPorts 方法
            MyAPI.log(`Received list: ${list}`); // 打印返回的串口列表
            if (list && list.length > 0) {

                my_port.innerHTML = '';
                // 添加默认 "None" 选项
                addOption('0', 'None', my_port);

                // 动态添加串口选项
                list.forEach((element) => {
                    if (element.manufacturer != null && element.manufacturer != 'undefined') {
                        //新增串口选项 
                        addOption(element.path, element.manufacturer, my_port);
                    }
                });

                ///显示当前连接端口
                port = await serialAPI.currentPort();
                if (port != null) {
                    my_port.value = port.path;
                    MyAPI.log(`======>查看当前连接的端口：  path:${port.path}   manufacturer:${port.manufacturer}`);
                }
            } else {
                MyAPI.log('没有找到端口！！！');
            }
        } catch (error) {
            MyAPI.log(`获取端口失败 ${error}`);
            console.error('Error retrieving serial ports:', error);
        }
    }

    ///监听打开端口结果
    serialAPI.listenPort((_, result) => {
        if (!result.error) {
            if (result.isopen && !result.received && !result.send) {
                //端口 已经 打开
                if (result.msg) {
                    ///发送数据
                    serialAPI.sendDataWithList(0xFF, cmd);
                }
                //端口收到的 电脑下发的数据
                else if (result.received) {
                    // MyAPI.log(`======== ${result.received}`);
                }
                //电脑收到的 端口上发的数据
                else if (result.send) {
                    const bytes = result.send.hexStringToUint8Array();
                    if (bytes[0] == 0xFF && bytes[1] == 0x04) {
                        switch (bytes[2]) {
                            case 0x01://修改成功 
                                break;
                            case 0x02:
                                alert(`地址不正确，修改失败`);
                                break;
                            case 0x03:
                                alert(`校验不对，修改失败`);
                                break;
                            case 0x04:
                                alert(`信号类型不对，修改失败`);
                                break;
                            case 0x05:
                                alert(`异常，修改失败`);
                                break;
                            default:
                                break;
                        }
                    }
                    // MyAPI.log(`======== ${result.send}`);
                }
            } else {
                // MyAPI.log(`======== ${result.msg}`);
            }
        }
    });

    ///监听打开窗口时候，是选择检查还是修改
    MyAPI.onDisplayFile((event, new_cmd) => {
        cmd = new_cmd;
        loadModel();
    });

    ///更新本地数据
    async function updateLocal() {

        //保存波特率
        electronStoreAPI.set(baud_key, `${my_baud.value}`);

        //保存采样频率
        electronStoreAPI.set(frequency_key, `${frequency.value}`);

        //保存地址列表 
        const promises = address_list.map(async (model, index) => {
            try {
                ///如果是修改值
                if (cmd == 0x05) {
                    model.changeValue = document.getElementById(`my_address_input${index}`).value;
                } else {
                    model.address = document.getElementById(`my_address_input${index}`).value;
                }
                model.signalType = document.getElementById(`my_sign_type${index}`).value;
                model.flag = document.getElementById(`my_flag${index}`).value;
                return await AddressAPI.updateAddress(model);
            } catch (error) {
                MyAPI.log(`保存地址错误：${error}`);
                return { success: false, error: error.message || "未知错误" };
            }
        });

        const results = await Promise.all(promises);
        // 处理结果
        const failedResults = results.filter(result => !result.success);
        if (failedResults.length > 0) {
            alert(`部分地址保存失败:\n${failedResults.map(res => res.error).join("\n")}`);
        } else {
            //全部更新完成后，打开串口端口
            serialAPI.openPort(my_port.value, `${my_port.options[my_port.selectedIndex].text}`, Number(my_baud.value));
        }
    }

    ///添加select元素的option
    function addOption(value, textContent, selectElement) {
        const defaultOption = document.createElement('option');
        defaultOption.value = `${value}`;
        defaultOption.textContent = `${textContent}`;
        selectElement.appendChild(defaultOption);
    }

    ///调整窗口大小
    function adjustWindowSize() {
        // const width = document.body.scrollWidth;
        // const height = document.body.scrollHeight;
        // console.log(`调整窗口大小: ${width} x ${height}`);
        // MyAPI.setWindowSize(width + 10, height );
    }

    //动态加载地址个数
    const container = document.getElementById('my_address_container');
    const item = document.getElementById('my_address_item_temp');
    const first_address = 0x000000FF;
    async function loadModel() {
        address_list = await AddressAPI.getAllAddresses;
        // 清空容器
        container.innerHTML = '';
        // 循环生成多个通道项
        for (let i = 0; i < address_list.length; i++) {
            const model = address_list[i];

            // 克隆模板
            const clone = document.importNode(item.content, true);

            // 获取克隆的元素
            const name = clone.querySelector('.my_address_name');
            const input = clone.querySelector('.my_address_input');
            const select = clone.querySelector('.my_sign_type');
            const select2 = clone.querySelector('.my_flag');


            const optionsMap1 = new Map([
                ["uint16", "001"],
                ["int16", "010"],
                ["uint32", "011"],
                ["int32", "100"],
                ["float", "101"],
                ["bool", "110"]
            ]);

            const optionsMap2 = new Map([
                ["高", "1"],
                ["低", "0"]
            ]);


            optionsMap1.forEach((value, key) => {
                addOption(value, key, select);
            });

            optionsMap2.forEach((value, key) => {
                addOption(value, key, select2);
            })

            ///设置内容
            name.textContent = `地址${i + 1}`;
            const n = (i * 0xFFFFF * first_address).toString(16).toUpperCase().padStart(8, '0');
            //input.value = `${n}`;
            input.value = cmd == 0x05 ? model?.changeValue : model?.address;
            select.value = model?.signalType;
            select2.value = model?.flag;


            // 设置动态 ID
            name.setAttribute('id', `my_address_name${i}`);
            input.setAttribute('id', `my_address_input${i}`);
            select.setAttribute('id', `my_sign_type${i}`);
            select2.setAttribute('id', `my_flag${i}`);

            // 将克隆的元素添加到容器中
            container.appendChild(clone);

            input.addEventListener('input', () => {
                console.log(` ${name.textContent} 的输入值是: ${input.value}`);
            })

            select.addEventListener('change', function () {
                console.log(` ${name.textContent} 的信号类型是: ${select.value}`);
            });
        }
    }

    window.onload = adjustWindowSize;
    window.onresize = adjustWindowSize;
    refreshPortList();

</script>

</html>